package com.yangxk.kadmin.web.module.system.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.yangxk.kadmin.common.base.AbstractService;
import com.yangxk.kadmin.common.beans.Page;
import com.yangxk.kadmin.common.exception.BizException;
import com.yangxk.kadmin.common.exception.ParamException;
import com.yangxk.kadmin.common.support.generator.IdGenerator;
import com.yangxk.kadmin.common.util.StringUtil;
import com.yangxk.kadmin.common.util.ValidUtil;
import com.yangxk.kadmin.web.common.enumeration.ResponseCode;
import com.yangxk.kadmin.web.module.system.form.RoleEditForm;
import com.yangxk.kadmin.web.module.system.form.RoleQueryForm;
import com.yangxk.kadmin.web.module.system.mapper.RoleMapper;
import com.yangxk.kadmin.web.module.system.po.Role;
import com.yangxk.kadmin.web.module.system.po.RoleAuth;
import com.yangxk.kadmin.web.module.system.service.AuthService;
import com.yangxk.kadmin.web.module.system.service.DeptService;
import com.yangxk.kadmin.web.module.system.service.RoleService;
import com.yangxk.kadmin.web.module.system.vo.AuthTree;
import com.yangxk.kadmin.web.module.system.vo.DeptTree;
import com.yangxk.kadmin.web.module.system.vo.RoleAuthVo;
import com.yangxk.kadmin.web.module.system.vo.RoleDeptVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class RoleServiceImpl extends AbstractService<Role, Long> implements RoleService {

    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private AuthService authService;
    @Autowired
    private DeptService deptService;

    @Override
    public Page<Role> queryByPage(RoleQueryForm roleQueryForm) {

        PageHelper.startPage(roleQueryForm.getPageNum(), roleQueryForm.getPageSize());

        List<Role> roleList = roleMapper.selectList(roleQueryForm);

        return new Page(new PageInfo(roleList));
    }

    /**
     * 添加角色
     * create by yangxk on 2018/10/16 16:14
     */
    @Transactional
    @Override
    public long addRole(RoleEditForm form) {
        Role role = new Role();
        BeanUtils.copyProperties(form, role);

        role.setId(IdGenerator.getId());
        roleMapper.insertSelective(role);

        return role.getId();
    }

    /**
     * 修改角色
     * create by yangxk on 2018/10/16 16:15
     */
    @Override
    @Transactional
    public long updateRole(RoleEditForm form) {
        if (form.getId() == null)
            throw new ParamException("id不能为空");

        Role role = roleMapper.selectByPrimaryKey(form.getId());
        if (role == null)
            throw new BizException(ResponseCode.UPDATE_CHECK_NULL);

        Role update = new Role();
        BeanUtils.copyProperties(form, update);
        roleMapper.updateByPrimaryKeySelective(update);

        return role.getId();
    }

    /**
     * 删除角色
     * create by yangxk on 2018/10/16 16:35
     */
    @Override
    @Transactional
    public void deleteRole(long id) {
        Role role = roleMapper.selectByPrimaryKey(id);
        if (role == null)
            throw new BizException(ResponseCode.UPDATE_CHECK_NULL);
        List<Long> roleUser = roleMapper.findRoleUser(id);
        if (!ValidUtil.isEmpty(roleUser))
            throw new BizException(ResponseCode.DELETE_ROLE_FAIL);

        // 删除角色
        roleMapper.deleteByPrimaryKey(id);
        // 删除角色权限
        roleMapper.deleteAuth(id);
    }


    /**
     * 分配权限
     * create by yangxk 2018/10/14 14:36
     */
    @Transactional
    @Override
    public List<Long> setAuth(long roleId, Long[] authIds) {
        if (ValidUtil.isEmpty(authIds))
            throw new ParamException("权限不能为空");

        Role role = roleMapper.selectByPrimaryKey(roleId);
        if (role == null)
            throw new BizException(ResponseCode.UPDATE_CHECK_NULL);

        // 删除当前角色权限
        roleMapper.deleteAuth(roleId);

        // 插入角色权限
        return addAuth(roleId, Arrays.asList(authIds));
    }

    /**
     * 为角色添加权限
     * create by yangxk on 2018/10/22 14:57
     */
    @Transactional
    @Override
    public List<Long> addAuth(long roleId, List<Long> authIds) {
        if (ValidUtil.isEmpty(authIds))
            throw new ParamException("权限不能为空");

        // 构造RoleAuth对象
        int len = authIds.size();
        List<RoleAuth> raList = new ArrayList<>(len);
        RoleAuth ra = null;
        for (Long authId : authIds) {
            ra = new RoleAuth(IdGenerator.getId(), roleId, authId);

            raList.add(ra);
        }
        // 插入角色权限
        roleMapper.insertAuth(raList);

        return raList.stream().map(item -> item.getId()).collect(Collectors.toList());
    }

    /**
     * 查询角色权限集合
     * create by yangxk 2018/10/14 15:15
     */
    @Override
    public RoleAuthVo findRoleAuth(long roleId) {
        Role role = roleMapper.selectByPrimaryKey(roleId);
        if (role == null)
            return new RoleAuthVo();

        List<AuthTree> authTree = authService.queryAuthTree();
        List<Long> roleAuthId = roleMapper.findRoleAuth(roleId);

        return new RoleAuthVo(authTree, roleAuthId);
    }

    /**
     * 查询角色的数据权限(部门)
     * create by yangxk on 2019/2/2 17:41
     */
    @Override
    public RoleDeptVo findRoleDept(long roleId) {
        Role role = roleMapper.selectByPrimaryKey(roleId);
        if (role == null)
            return new RoleDeptVo();

        String deptIds = role.getDeptIds();

        List<Long> roleDeptIds = new ArrayList<>();

        if (!ValidUtil.isEmpty(deptIds)) {
            String[] ids = StringUtil.str2Arr(deptIds);
            for (String id : ids) {
                roleDeptIds.add(Long.valueOf(id));
            }
        }

        List<DeptTree> deptTree = deptService.queryDeptTree();

        return new RoleDeptVo(deptTree, roleDeptIds);
    }

    /**
     * 为角色设置数据权限(deptId)
     * create by yangxk on 2019/2/2 17:46
     */
    @Override
    @Transactional
    public void setDept(long roleId, Long[] deptIds) {
        Role role = roleMapper.selectByPrimaryKey(roleId);
        if (role == null)
            throw new BizException(ResponseCode.ILLEGAL_PARAM);

        String str = StringUtil.arr2String(deptIds);
        role.setDeptIds(str);

        roleMapper.updateByPrimaryKey(role);
    }
}
